<template>
  <div class="container">
    <el-divider content-position="left"><span class="title-left-color">基本信息</span></el-divider>
    <el-form ref="formRef" :model="form" :rules="rules" v-loading="loading" label-width="150px">
      <el-row :gutter="10">
        <el-col :span="11">
          <el-form-item label="商品分类：" prop="category_id">
            <el-select v-model.trim="form.category_id" placeholder="商品分类" clearable>
              <el-option v-for="item in categoryList" :label="item.name" :value="item.id" :key="item.id"></el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="1">
          <el-button type="primary" plain @click="handleRefresh">刷新</el-button>
        </el-col>
        <el-col :span="12">
          <el-form-item label="商品名称：" prop="name">
            <el-input v-model.trim="form.name" placeholder="商品名称"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="商品货号：" prop="goods_sn">
            <el-input v-model.trim="form.goods_sn" placeholder="商品货号"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="最高估价：" prop="price">
            <el-input v-model.trim="form.price" placeholder="最高估价"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="是否上架：" prop="on_sale">
            <el-select v-model.trim="form.on_sale" placeholder="是否上架" clearable class="">
              <el-option v-for="item in whetherStatue" :label="item.dictLabel" :value="item.dictValue" :key="item.id"></el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="排序：" prop="sort">
            <el-input v-model.trim="form.sort" placeholder="排序"></el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="10">
        <el-col :span="24">
          <el-form-item label="商品别名：" prop="alias">
            <div class="draggable-info">
              <draggable v-model="form.alias" group="alias" animation="500" class="w-continer">
                <el-tag size="large" :key="tag" v-for="tag in form.alias" closable :disable-transitions="false" @close="handleClose(tag)">
                  {{ tag }}
                </el-tag>
              </draggable>
              <el-input class="input-new-tag" v-if="inputVisible" v-model="inputValue" ref="tagInputRef" @keyup.enter="handleInputConfirm" @blur="handleInputConfirm"> </el-input>
              <el-button v-else class="button-new-tag" @click="showInput">新增别名</el-button>
            </div>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="10">
        <el-col :span="12">
          <el-form-item label="主图：" prop="image">
            <UploadImageInfo :imageWidth="178" :imageHeight="178" v-model:disabledbtn="disabledbtn" v-model:loading="loading" imageKey="image" v-model:form="form" suggestInfo="建议：尺寸750x530像素(等比例亦可)，大小500k以下" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-divider content-position="left"><span class="title-left-color">回收估价</span></el-divider>
      <div class="recovery-valuation-info">
        <div v-for="(item, index) in recycledGoodsTypeList" :key="item.id">
          <div class="r-title">{{ item.name }}：</div>
          <el-row :gutter="20">
            <el-col :span="8" v-for="(_item, _index) in item.children" :key="_item.id">
              <el-form-item :label="_item.name + '：'">
                <el-input v-model.trim="recycledGoodsTypeList[index].children[_index].price" :placeholder="item.name">
                  <template #prepend>减</template>
                  <template #append>元</template>
                </el-input>
              </el-form-item>
            </el-col>
          </el-row>
        </div>
      </div>
    </el-form>
    <div class="footer-center">
      <el-button :disabled="disabledbtn" @click="cancelSubmit">取 消</el-button>
      <el-button :disabled="disabledbtn" @click="handleViewEstimate">查看估价</el-button>
      <el-button type="primary" :disabled="disabledbtn" v-if="!isDisabledbtn" @click="submitForm">确 定</el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { VueDraggableNext as draggable } from "vue-draggable-next";
import UploadImageInfo from "@/components/common/UploadImageInfo.vue";
import type { postOrPutType } from "@/constants";
import type { HasId, ViewMode } from "@/types/common";
import { useState } from "@/hooks/useState.ts";
import type { IDictData } from "@/types/dict";
import type { IRecycleCategory } from "@/types/recoveryManage/recycleCategory";
import type { IEstimate, RecycledGoodsDetail, RecycledGoodsDetailDTO, IRecycleType } from "@/types/recoveryManage/recycledGoodsInfo";
import { commonRecycleGoodsInfo, getRecycleGoodsByIdInfo } from "@/utils/api/recycleGoods";
import type { ISearchRecoveryType } from "@/types/recoveryManage/recoveryType";
import { getRecycleTypelInfo } from "@/utils/api/recycleType";
const { disabledbtn, loading, toggleState } = useState();

interface Props {
  id: number;
  categoryList: Array<IRecycleCategory>;
  whetherStatue: Array<IDictData>;
}
const { id, categoryList, whetherStatue } = defineProps<Props>();
const formStatus = defineModel<ViewMode>("formStatus", { required: true });

const emit = defineEmits<{
  handleInitData: [];
  handleSuccess: [];
  handleRefresh: [];
  handleViewEstimate: [id: number, estimateColumnList: Array<string>, estimateList: Array<IEstimate>];
}>();

const isDisabledbtn = ref(false);
const inputVisible = ref(false);
/* 别名值 */
const inputValue = ref("");
const formRef = useTemplateRef("formRef");
const tagInputRef = useTemplateRef("tagInputRef");
const methodType = ref<postOrPutType>("PUT");

const recycledGoodsTypeList = ref<Array<IRecycleType>>([]);
const recycleTypeList = ref<Array<IRecycleType>>([]);
const estimateColumnList = ref<Array<string>>([]);
const estimateList = ref<Array<IEstimate>>([]);

const rules = reactive({
  category_id: [{ required: true, message: "请选择商品分类", trigger: "blur" }],
  name: [{ required: true, message: "请填写商品名称", trigger: "blur" }],
  price: [{ required: true, message: "请填写最高估价", trigger: "blur" }],
  on_sale: [{ required: true, message: "请选择是否上架", trigger: "blur" }],
  sort: [{ required: true, message: "请填写排序", trigger: "blur" }],
  image: [{ required: true, message: "请上传主图", trigger: "blur" }]
});
const form = reactive<RecycledGoodsDetailDTO>({
  id: 0,
  category_id: "",
  goods_sn: "",
  name: "",
  price: "",
  image: "",
  on_sale: "",
  sort: 0,
  category_name: "",
  type: [],
  alias: []
});
onMounted(() => {
  console.log("Component mounted!");
});

/* formStatus处理器 */
const statusHandlers: Record<ViewMode, () => void> = {
  view: () => {
    isDisabledbtn.value = true;
  },
  edit: () => {
    methodType.value = "PUT";
  },
  add: () => {
    methodType.value = "POST";
  },
  none: () => {
    /* 初始化数据 */
    handleInitData();
  }
};
/* 监听formStatus,新增，编辑，查看的时候都可以打开模态框，又是有不同的操作和效果，需要单独判断，none为模态框关闭的情况，需要初始化数据 */
watch(formStatus, newValue => {
  const handler = statusHandlers[newValue];
  handler?.();
});
watch(
  () => id,
  newValue => {
    if (newValue == 0) {
      /* 初始化数据 */
    } else {
      form.id = newValue;
      handleGetInfoById(id);
    }
  }
);
/* 刷新发布主体 */
function handleRefresh() {
  emit("handleRefresh");
}
/* 获取回收类型 */
function handleGetRecycleTypelInfo() {
  toggleState(true);
  getRecycleTypelInfo<Array<IRecycleType>, ISearchRecoveryType>({ children: 1 })
    .then(res => {
      recycledGoodsTypeList.value = res.result;
      recycleTypeList.value = JSON.parse(JSON.stringify(res.result));
    })
    .finally(() => {
      toggleState(false);
    });
}
/* 通过id获取情信息 */
function handleGetInfoById(id: number) {
  toggleState(true);
  getRecycleGoodsByIdInfo<RecycledGoodsDetail, HasId>({ id })
    .then(res => {
      form.id = res.result.id;
      form.category_id = res.result.category_id;
      form.goods_sn = res.result.goods_sn;
      form.name = res.result.name;
      form.alias = res.result.alias;
      form.price = res.result.price;
      form.image = res.result.image;
      form.on_sale = res.result.on_sale;
      form.sort = res.result.sort;
      recycledGoodsTypeList.value = res.result.type;
    })
    .catch(() => {})
    .finally(() => {
      toggleState(false);
    });
}

/* 初始化数据 */
function handleInitData() {
  methodType.value = "POST";
  isDisabledbtn.value = false;
  recycledGoodsTypeList.value = JSON.parse(JSON.stringify(recycleTypeList.value));
  formRef.value?.resetFields();
  formRef.value?.clearValidate();
}

/* 保存或编辑 */
function submitForm() {
  if (!formRef.value) return;
  formRef.value.validate(valid => {
    if (!valid) {
      ElMessage.warning("请填写必填字段");
      return;
    }
    submitFormInfo();
  });
}

/* 保存或编辑信息 */
function submitFormInfo() {
  /* 防止多次提交 */
  toggleState(true);
  handleInitType();
  commonRecycleGoodsInfo(form, methodType.value)
    .then(res => {
      ElMessage.success(res.msg);
      cancelSubmit();
      emit("handleSuccess");
    })
    .catch(() => {})
    .finally(() => {
      toggleState(false);
    });
}
/* 保存或编辑 取消提交 */
function cancelSubmit() {
  // clearData();
  // activeName = "one";
  emit("handleInitData");
}

/* 初始化回收类型 */
function handleInitType() {
  form.type = [];
  for (const item of recycledGoodsTypeList.value) {
    form.type.push(...item.children);
  }
}

/* 关闭别名输入 */
function handleClose(tag: string) {
  form.alias.splice(form.alias.indexOf(tag), 1);
}

/* 点击输入，获取焦点 */
function showInput() {
  inputVisible.value = true;
  nextTick(() => {
    if (tagInputRef.value) {
      const inputElement = tagInputRef.value.$el.querySelector("input");
      if (inputElement) {
        inputElement.focus();
      }
    }
  });
}

/* 保存 */
function handleInputConfirm() {
  if (form.alias.includes(inputValue.value)) {
    ElMessage.warning(`${inputValue.value}商品别名已存在`);
    return;
  }
  if (inputValue.value) {
    form.alias.push(inputValue.value);
  }
  inputVisible.value = false;
  inputValue.value = "";
}
/* 校验是否可以查看估价 */
function handleVerifyEstimate() {
  if (form.price === "") {
    ElMessage.warning(`请先填写最高估价信息`);
    return false;
  }
  return true;
}
/* 查看估价 */
function handleViewEstimate() {
  if (!handleVerifyEstimate()) return;
  estimateColumnList.value = [];
  estimateList.value = [];
  estimateColumnList.value.push(...recycledGoodsTypeList.value.map(item => item.name));
  let n = 1;
  for (let i = 0; i < recycledGoodsTypeList.value.length; i++) {
    const l = recycledGoodsTypeList.value[i].children.length;
    if (l !== 0) {
      n *= l;
    }
  }
  for (let i = 0; i < n; i++) {
    let obj: IEstimate = {
      price: 0
    };
    estimateList.value.push(obj);
  }
  for (let i = 0; i < recycledGoodsTypeList.value.length; i++) {
    const item = recycledGoodsTypeList.value[i];
    const c_l = item.children.length;
    for (let k = 0; k < estimateList.value.length; k++) {
      let j = k % c_l;
      estimateList.value[k]["v" + i] = item.children[j].name;
      if (item.children[j].price !== undefined) {
        estimateList.value[k]["p" + i] = Number(item.children[j].price);
      } else {
        estimateList.value[k]["p" + i] = 0;
      }
    }
  }
  handleFinalValuation();
  emit("handleViewEstimate", id, estimateColumnList.value, estimateList.value);
}
/* 计算最终估价 */
function handleFinalValuation() {
  const e_c_l = estimateColumnList.value.length;
  /* 计算最终估价 */
  for (let i = 0; i < estimateList.value.length; i++) {
    let sum = Number(form.price);
    for (let j = 0; j < e_c_l; j++) {
      const key = "p" + j;
      sum -= Number(estimateList.value[i][key]);
    }
    estimateList.value[i].price = sum;
  }
}

handleGetRecycleTypelInfo();
</script>

<style lang="scss" scoped>
/* 修改select的盒模型 */
.el-select {
  display: block;
}
/* 底部按钮居中 */
.footer-center {
  margin: 10px 0;
  text-align: center;
}

.w-continer {
  display: flex;
  align-items: center;
  gap: 10px;
}
.draggable-info {
  display: flex;
  align-items: center;
  gap: 10px;
}

.recovery-valuation-info {
  margin: 20px 50px;
  .r-title {
    margin-bottom: 20px;
    margin-left: 20px;
    font-weight: bold;
  }
}
</style>
